package com.ruoyi.system.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.data.style.Style;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysQuestion;
import com.ruoyi.common.core.domain.entity.SysQuestionDomain;
import com.ruoyi.common.core.domain.entity.SysQuestionRecord;
import com.ruoyi.system.domain.SysCompanyMember;
import com.ruoyi.system.domain.SysNaire;
import com.ruoyi.system.domain.vo.BasisInfoVo;
import com.ruoyi.system.domain.vo.DomainInfoItemVo;
import com.ruoyi.system.domain.vo.SysQuestionReqVo;
import com.ruoyi.system.dto.QuestionDomainScore;
import com.ruoyi.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysCompanyDiagnosis;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import utils.ExcelResponse;
import utils.ScoreUtils;

/**
 * 现场诊断记录Controller
 * 
 * @author ruoyi
 * @date 2023-09-11
 */
@Api(tags = "现场诊断记录")
@RestController
@RequestMapping("/system/diagnosis")
public class SysCompanyDiagnosisController extends BaseController
{
    @Autowired
    private ISysCompanyDiagnosisService sysCompanyDiagnosisService;


    @Autowired
    private ISysQuestionDomainService domainService;

    @Autowired
    private ISysQuestionService sysQuestionService;

    @Autowired
    private ISysNaireService sysNaireService;

    @Autowired
    private ISysQuestionRecordService sysQuestionRecordService;

    @Autowired
    private ISysCompanyMemberService sysCompanyMemberService;

    @Autowired
    private ISysDeptService deptService;

    /** 现场评测表导出模板路径 */
    public static final String DIAGNOSIS_RECORD_WORD_TEMPLATE_PATH = "templates/word/diagnosis_record.docx";

    /** 现场评测表导出模板路径 */
    public static final String DIAGNOSIS_RECORD_2_WORD__TEMPLATE_PATH = "templates/word/diagnosis_record_2.docx";

    /** 现场评测表导出模板路径 */
    public static final String DIAGNOSIS_RECORD_3_WORD__TEMPLATE_PATH = "templates/word/diagnosis_record_3.docx";

    public static final String DIAGNOSIS_RECORD_4_WORD__TEMPLATE_PATH = "templates/word/diagnosis_record_4.docx";
    /**
     * 查询现场诊断记录列表
     */
  //  @PreAuthorize("@ss.hasPermi('system:diagnosis:list')")
    @GetMapping("/list")
   // @ApiOperation(value = "查询现场诊断记录列表")
    public AjaxResult list(SysCompanyDiagnosis sysCompanyDiagnosis)
    {
        List<SysCompanyDiagnosis> list = sysCompanyDiagnosisService.selectSysCompanyDiagnosisList(sysCompanyDiagnosis);
        return AjaxResult.success(list);
    }

    /**
     * 导出现场诊断记录列表
     */
 //   @PreAuthorize("@ss.hasPermi('system:diagnosis:export')")
    @Log(title = "现场诊断记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysCompanyDiagnosis sysCompanyDiagnosis)
    {
        List<SysCompanyDiagnosis> list = sysCompanyDiagnosisService.selectSysCompanyDiagnosisList(sysCompanyDiagnosis);
        ExcelUtil<SysCompanyDiagnosis> util = new ExcelUtil<SysCompanyDiagnosis>(SysCompanyDiagnosis.class);
        util.exportExcel(response, list, "现场诊断记录数据");
    }


    /**
     * 获取现场诊断记录详细信息
     */
    //  @PreAuthorize("@ss.hasPermi('system:diagnosis:query')")
    @GetMapping(value = "/{deptId}")
    @ApiOperation(value = "获取现场诊断记录详细信息")
    public AjaxResult getInfo(@PathVariable("deptId") Long deptId)
    {
        return AjaxResult.success(sysCompanyDiagnosisService.selectSysCompanyDiagnosisByCompanyId(deptId));
    }


    /**
     * 新增现场诊断记录
     */
 //   @PreAuthorize("@ss.hasPermi('system:diagnosis:add')")
    @Log(title = "现场诊断记录", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation(value = "新增现场诊断记录")
    public AjaxResult add(@RequestBody SysCompanyDiagnosis sysCompanyDiagnosis)
    {
        return toAjax(sysCompanyDiagnosisService.insertSysCompanyDiagnosis(sysCompanyDiagnosis));
    }

    /**
     * 修改现场诊断记录
     */
  //  @PreAuthorize("@ss.hasPermi('system:diagnosis:edit')")
    @Log(title = "现场诊断记录", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation(value = "修改现场诊断记录")
    public AjaxResult edit(@RequestBody SysCompanyDiagnosis sysCompanyDiagnosis)
    {
        return toAjax(sysCompanyDiagnosisService.updateSysCompanyDiagnosis(sysCompanyDiagnosis));
    }

    /**
     * 修改现场诊断记录
     */
    //  @PreAuthorize("@ss.hasPermi('system:diagnosis:edit')")
    @Log(title = "现场诊断记录", businessType = BusinessType.UPDATE)
    @PutMapping("/domain")
    @ApiOperation(value = "修改现场诊断记录(报告信息)")
    public AjaxResult updateSysCompanyDiagnosisDomain(@RequestBody SysCompanyDiagnosis sysCompanyDiagnosis)
    {
        return toAjax(sysCompanyDiagnosisService.updateSysCompanyDiagnosisDomain(sysCompanyDiagnosis));
    }

    /**
     * 删除现场诊断记录
     */
 //   @PreAuthorize("@ss.hasPermi('system:diagnosis:remove')")
    @Log(title = "现场诊断记录", businessType = BusinessType.DELETE)
	@DeleteMapping("/{diagnosisIds}")
//    @ApiOperation(value = "删除现场诊断记录")
    public AjaxResult remove(@PathVariable Long[] diagnosisIds)
    {
        return toAjax(sysCompanyDiagnosisService.deleteSysCompanyDiagnosisByDiagnosisIds(diagnosisIds));
    }

    /**
     * 现场诊断记录结束评分
     * @param deptId
     */
    @ApiOperation(value = "现场诊断记录结束评分")
    @Log(title = "现场诊断记录结束评分", businessType = BusinessType.UPDATE)
    @PutMapping("/end/{deptId}")
    public AjaxResult diagnosisEnd(@PathVariable("deptId") Long deptId)
    {
        int result=sysCompanyDiagnosisService.diagnosisEnd(deptId);

        return toAjax(result);
    }


    /**
     * 查询企业现场测评表分数
     */
    @ApiOperation(value = "查询企业现场测评表分数")
    // @PreAuthorize("@ss.hasPermi('system:company:list')")
    @GetMapping("/scene/score")
    public AjaxResult selectCompanyDiagnoseRecordScore(SysQuestionReqVo questionReqVo)
    {
        SysNaire naire = sysNaireService.selectSysNaireByNaireId(questionReqVo.getNaireId());

        Set<Long> questionIdList = Arrays.stream(naire.getQuestions().substring(1, naire.getQuestions().length() - 1).split(","))
                .map(s -> Long.parseLong(s.trim()))
                .collect(Collectors.toSet());

        List<SysQuestion> questions = sysQuestionService.selectSysQuestionByQuestionIds(questionIdList);

        SysQuestionRecord query=new SysQuestionRecord();
        query.setCompanyId(questionReqVo.getCompanyId());
        query.setNaireId(questionReqVo.getNaireId());
        query.setQuestionId(questionReqVo.getQuestionId());
        query.setUserId(getLoginUser().getUserId());
        List<SysQuestionRecord>  questionRecords=sysQuestionRecordService.selectSysQuestionRecordList(query);

        List<List<SysQuestionRecord>> resultList = ScoreUtils.groupDataByCondition(questionRecords,new Comparator<SysQuestionRecord>(){
            @Override
            public int compare(SysQuestionRecord o1, SysQuestionRecord o2) {
                return o1.getQuestionId().equals(o2.getQuestionId()) ? 0 : -1;
            }
        });

        if(CollUtil.isNotEmpty(questions)){
            for (SysQuestion question:questions){
                if(CollUtil.isNotEmpty(resultList)){
                    for (List<SysQuestionRecord> list : resultList) {
                        if(list.get(0).getQuestionId().equals(question.getQuestionId())){
                            question.setRecords(list);
                            break;
                        }
                    }
                }
            }
        }

        List<List<SysQuestion>> questionList= ScoreUtils.groupDataByCondition(questions,new Comparator<SysQuestion>(){
            @Override
            public int compare(SysQuestion o1, SysQuestion o2) {
                return o1.getDomain().equals(o2.getDomain()) ? 0 : -1;
            }
        });

        Set<Long> domainsIdList = questionList.stream().map(questions1 -> questions1.get(0).getDomain().longValue())
                .collect(Collectors.toSet());



        List<SysQuestionDomain> domains = domainService.selectQuestionDomainListByIds(domainsIdList);

        // 三级指标分数
        List<QuestionDomainScore> secondDomainScores=new ArrayList<>();
        for (SysQuestionDomain sysQuestionDomain:domains){
            for (List<SysQuestion> sysQuestions:questionList){
                if(sysQuestionDomain.getDomainId().equals(sysQuestions.get(0).getDomain())){
                    secondDomainScores.add(ScoreUtils.getDomainScore(sysQuestionDomain,sysQuestions));
                    break;
                }
            }

        }

        return AjaxResult.success(secondDomainScores);
    }


    @ApiOperation(value = "导出现场诊断记录表")
    @GetMapping("/record/word/{deptId}")
    public void exportDigitalTestWord(@PathVariable("deptId") Long deptId,HttpServletResponse response) throws IOException {

        Configure config = Configure.builder()
                // isStrict = false , 关闭严格模式, 严格模式下key不存在会报错
                // 关闭后key不存在会被忽略
                // .useSpringEL(true)
                // 表格绑定policy
                .build();

        ClassPathResource classPathResource = new ClassPathResource(DIAGNOSIS_RECORD_WORD_TEMPLATE_PATH);

        SysCompanyMember sysCompanyMember=new SysCompanyMember();
        sysCompanyMember.setDeptId(deptId);
        // 组长
        sysCompanyMember.setMemberType("1");
        SysCompanyDiagnosis sysCompanyDiagnosis=sysCompanyDiagnosisService.selectSysCompanyDiagnosisByCompanyId(deptId);

        List<SysCompanyMember> list = sysCompanyMemberService.selectSysCompanyMemberList(sysCompanyMember);

        BasisInfoVo basisInfoVo = JSONUtil.toBean(sysCompanyDiagnosis.getBasisInfo(), BasisInfoVo.class);

        List<DomainInfoItemVo> domainInfoItemVos = JSONUtil.toList(sysCompanyDiagnosis.getDomainInfo(), DomainInfoItemVo.class);

        Map<String, Object> map=new HashMap<String, Object>();

        map.put("companyNum",sysCompanyDiagnosis.getCompanyNum());
        map.put("recordNum",sysCompanyDiagnosis.getRecordNum());
        map.put("diagnosisTime", DateUtil.formatDate(sysCompanyDiagnosis.getDiagnosisTime()));
        map.put("registerAddress",basisInfoVo.getRegisterAddress());
        map.put("realAddress",basisInfoVo.getRealAddress());
        map.put("realName",basisInfoVo.getRealName());
        map.put("phone",basisInfoVo.getPhone());
        map.put("email",basisInfoVo.getEmail());
        map.put("postcode",basisInfoVo.getPostcode());
        map.put("address",basisInfoVo.getAddress());
        map.put("telephone",basisInfoVo.getTelephone());
        map.put("time",basisInfoVo.getTime());
        map.put("business",basisInfoVo.getBusiness());

        if(CollUtil.isNotEmpty(list)){
            map.put("member",list.get(0).getNickName());
        }
        if(CollUtil.isNotEmpty(domainInfoItemVos)){
            for (DomainInfoItemVo domainInfoItemVo:domainInfoItemVos){
                map.put("content"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getContent());
                map.put("r"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getResult());
                map.put("time"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getTime());
            }
        }


        XWPFTemplate template = XWPFTemplate.compile(classPathResource.getInputStream(),config).render(map);
        OutputStream os = response.getOutputStream();
        // 响应到客户端
        ExcelResponse.disposition(response, "现场诊断记录表" + ".docx", "attachment", 0);
        template.write(os);
        os.flush();
        os.close();
        if (template != null) {
            template.close();
        }
    }


    @ApiOperation(value = "导出现场诊断报告")
    @GetMapping("/record2/word/{deptId}")
    public void exportCompanyDiagnosisRecord2Word(@PathVariable("deptId") Long deptId,HttpServletResponse response) throws IOException {

        Configure config = Configure.builder()
                // isStrict = false , 关闭严格模式, 严格模式下key不存在会报错
                // 关闭后key不存在会被忽略
                // .useSpringEL(true)
                // 表格绑定policy
                .build();

        ClassPathResource classPathResource = new ClassPathResource(DIAGNOSIS_RECORD_2_WORD__TEMPLATE_PATH);

        SysCompanyDiagnosis sysCompanyDiagnosis=sysCompanyDiagnosisService.selectSysCompanyDiagnosisByCompanyId(deptId);

        SysDept sysDept = deptService.selectDeptById(deptId);

        BasisInfoVo basisInfoVo = JSONUtil.toBean(sysCompanyDiagnosis.getBasisInfo(), BasisInfoVo.class);

        List<DomainInfoItemVo> domainInfoItemVos = JSONUtil.toList(sysCompanyDiagnosis.getDomainInfo(), DomainInfoItemVo.class);

        Map<String, Object> map=new HashMap<String, Object>();

        if(sysDept!=null){
            map.put("companyName",sysDept.getDeptName());
        }
        if(CollUtil.isNotEmpty(domainInfoItemVos)){
            for (DomainInfoItemVo domainInfoItemVo:domainInfoItemVos){
                map.put("content"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getContent());
                map.put("r"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getResult());
                map.put("time"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getTime());
            }
        }


        XWPFTemplate template = XWPFTemplate.compile(classPathResource.getInputStream(),config).render(map);
        OutputStream os = response.getOutputStream();
        // 响应到客户端
        ExcelResponse.disposition(response, "现场诊断报告" + ".docx", "attachment", 0);
        template.write(os);
        os.flush();
        os.close();
        if (template != null) {
            template.close();
        }
    }


    @ApiOperation(value = "导出现场诊断报告")
    @GetMapping("/record3/word/{deptId}")
    public void exportCompanyDiagnosisRecord3Word(@PathVariable("deptId") Long deptId,HttpServletResponse response) throws IOException {

        Configure config = Configure.builder()
                // isStrict = false , 关闭严格模式, 严格模式下key不存在会报错
                // 关闭后key不存在会被忽略
                // .useSpringEL(true)
                // 表格绑定policy
                .build();

        ClassPathResource classPathResource = new ClassPathResource(DIAGNOSIS_RECORD_4_WORD__TEMPLATE_PATH);

        SysCompanyDiagnosis sysCompanyDiagnosis=sysCompanyDiagnosisService.selectSysCompanyDiagnosisByCompanyId(deptId);

        SysDept sysDept = deptService.selectDeptById(deptId);

        BasisInfoVo basisInfoVo = JSONUtil.toBean(sysCompanyDiagnosis.getBasisInfo(), BasisInfoVo.class);

        List<DomainInfoItemVo> domainInfoItemVos = JSONUtil.toList(sysCompanyDiagnosis.getDomainInfo(), DomainInfoItemVo.class);

        Map<String, Object> map=new HashMap<String, Object>();

        if(sysDept!=null){
            map.put("companyName",sysDept.getDeptName());
        }
        if(CollUtil.isNotEmpty(domainInfoItemVos)){
            for (DomainInfoItemVo domainInfoItemVo:domainInfoItemVos){
                map.put("content"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getContent());
                map.put("r"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getResult());
                map.put("reason"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getReason());
                map.put("suggest"+domainInfoItemVo.getDomainId(),domainInfoItemVo.getSuggest());
            }
        }


        XWPFTemplate template = XWPFTemplate.compile(classPathResource.getInputStream(),config).render(map);
        OutputStream os = response.getOutputStream();
        // 响应到客户端
        ExcelResponse.disposition(response, sysDept.getDeptName()+"现场诊断报告" + ".docx", "attachment", 0);
        template.write(os);
        os.flush();
        os.close();
        if (template != null) {
            template.close();
        }
    }

}
